﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace CPPEI.Coolzon.UI.Views.Windows
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="originalSize">原始场景大小</param>
    /// <param name="fullSize">缩放后的场景大小</param>
    /// <param name="viewRegion">缩放后的可视区域大小</param>
    public delegate void ViewRegionMouseEventHandler(Size originalSize, Size fullSize, Rect viewRegion);
    /// <summary>
    /// OverviewWindow.xaml 的交互逻辑
    /// </summary>
    public partial class OverviewWindow : Window
    {
        public event ViewRegionMouseEventHandler ViewRegionMoving;
        public event ViewRegionMouseEventHandler ViewRegionMoved;

        public Size originalSize;
        public Size fullSize;
        public Rect viewRegion;
        public OverviewWindow()
        {
            InitializeComponent();

            this.PreviewMouseLeftButtonUp += OverviewWindow_PreviewMouseLeftButtonUp;
        }

        void OverviewWindow_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            OnViewRegionMoved();

            Debug.Write("OverviewWindow_PreviewMouseLeftButtonUp");
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="imageSource">场景图片</param>
        /// <param name="scale">缩放比率</param>
        /// <param name="viewRegion">可视区域</param>
        /// <param name="mousePtInScreen">鼠标在屏幕中的坐标</param>
        [Obsolete("使用带6个参数的重载")]
        public OverviewWindow(ImageSource imageSource, double scale, Rect viewRegion, Point mousePtInScreen)
        {
            InitializeComponent();

            Image image = new Image();
            image.Source = imageSource;
            image.Width = imageSource.Width * scale;
            image.Height = imageSource.Height * scale;

            this.Width = image.Width;
            this.Height = image.Height;
            image.Stretch = Stretch.Fill;
            canvas.Children.Add(image);

            Border border = new Border();
            border.BorderBrush = new SolidColorBrush(Colors.Black);
            border.BorderThickness = new Thickness(2);
            Canvas.SetLeft(border, viewRegion.Left * scale);
            Canvas.SetTop(border, viewRegion.Top * scale);
            border.Width = viewRegion.Width * scale;
            border.Height = viewRegion.Height * scale;
            canvas.Children.Add(border);

            this.RegisterName("viewRegion", border);
            this.RegisterName("screenPart", image);

            this.Left = mousePtInScreen.X + 200;
            this.Top = mousePtInScreen.Y - this.ActualHeight;

            originalSize = new Size(imageSource.Width, imageSource.Height);
            fullSize = new Size(image.Width, image.Height);
            viewRegion = new Rect(Canvas.GetLeft(border), Canvas.GetTop(border), border.Width, border.Height);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="visual">显示的wpf元素对象</param>
        /// <param name="originalWidth"></param>
        /// <param name="originalHeight"></param>
        /// <param name="scale"></param>
        /// <param name="viewRegion"></param>
        /// <param name="mousePtInScreen"></param>
        public OverviewWindow(Visual visual, double originalWidth, double originalHeight, double scale, Rect viewRegion, Point mousePtInScreen)
        {
            InitializeComponent();

            Rectangle image = new Rectangle();
            VisualBrush fillBrush = new VisualBrush(visual);
            fillBrush.Stretch = Stretch.UniformToFill;
            fillBrush.AlignmentX = AlignmentX.Left;
            fillBrush.AlignmentY = AlignmentY.Top;
            image.Fill = fillBrush;
            image.Width = originalWidth * scale;
            image.Height = originalHeight * scale;

            this.Width = image.Width;
            this.Height = image.Height;
            image.Stretch = Stretch.Fill;
            canvas.Children.Add(image);

            Border border = new Border();
            border.BorderBrush = new SolidColorBrush(Colors.Black);
            border.BorderThickness = new Thickness(2);
            Canvas.SetLeft(border, viewRegion.Left * scale);
            Canvas.SetTop(border, viewRegion.Top * scale);
            border.Width = viewRegion.Width * scale;
            border.Height = viewRegion.Height * scale;
            canvas.Children.Add(border);

            this.RegisterName("viewRegion", border);
            this.RegisterName("screenPart", image);

            this.Left = mousePtInScreen.X + 200;
            this.Top = mousePtInScreen.Y - this.ActualHeight;

            originalSize = new Size(originalWidth, originalHeight);
            fullSize = new Size(image.Width, image.Height);
            viewRegion = new Rect(Canvas.GetLeft(border), Canvas.GetTop(border), border.Width, border.Height);
        }

        public void OnViewRegionMoving()
        {
            if (ViewRegionMoving != null)
            {
                SetViewRegion();
                ViewRegionMoving(originalSize, fullSize, viewRegion);
            }
        }

        public void OnViewRegionMoved()
        {
            if (ViewRegionMoved != null)
            {
                ViewRegionMoved(originalSize, fullSize, viewRegion);
            }
        }
        public Border GetViewRegion()
        {
            return canvas.FindName("viewRegion") as Border;
        }
        public void SetBorderPosionX(int flag, double offsetLeft)
        {
            Border border = GetViewRegion();
            if (border == null) return;

            double dbLeft;
            bool canMove = CanMoveX(flag, offsetLeft, out dbLeft);
            if (canMove)
            {
                Canvas.SetLeft(border, dbLeft);
            }
        }

        public void SetBorderPosionY(int flag, double offsetTop)
        {
            Border border = GetViewRegion();
            if (border == null) return;

            double dbTop;
            bool canMove = CanMoveY(flag, offsetTop, out dbTop);
            if (canMove)
            {
                Canvas.SetTop(border, dbTop);
            }
        }

        private bool CanMoveX(int flag, double offsetLeft, out double dbLeft)
        {
            Border border = GetViewRegion();
            double dbTop = Canvas.GetTop(border);
            if (flag > 0)
            {
                dbLeft = Canvas.GetLeft(border) + offsetLeft;
            }
            else
            {
                dbLeft = Canvas.GetLeft(border) - offsetLeft;
            }
            Point borderScreenPoint = PointToScreen(new Point(dbLeft, dbTop));
            if (borderScreenPoint.X <= this.Left || borderScreenPoint.X >= this.Left + this.Width - border.Width) return false;
            return true;
        }

        private bool CanMoveY(int flag, double offsetTop, out double dbTop)
        {
            Border border = GetViewRegion();
            double dbLeft = Canvas.GetLeft(border);
            if (flag > 0)
            {
                dbTop = Canvas.GetTop(border) + offsetTop;
            }
            else
            {
                dbTop = Canvas.GetTop(border) - offsetTop;
            }
            Point borderScreenPoint = PointToScreen(new Point(dbLeft, dbTop));
            if (borderScreenPoint.Y <= this.Top || borderScreenPoint.Y >= this.Top + this.Height - border.Height) return false;
            return true;
        }

        public void SetViewRegion()
        {
            Border border = GetViewRegion();
            viewRegion = new Rect(Canvas.GetLeft(border)-border.BorderThickness.Left, Canvas.GetTop(border)-border.BorderThickness.Top, border.Width,border.Height);
        }
    }
}
